package com.cq.service;

import com.cq.mapper.SysFileMapper;
import com.cq.model.SysFile;
import com.cq.utils.DateUtils;
import com.cq.utils.Encry;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zhouqi
 */
@Service
public class SysFileService {

    @Autowired
    private SysFileMapper sysFileMapper;

    @Value("${sys.file.fileUploadPath}")
    private String uploadPath;

    @Value("${sys.file.fileUploaaPathWin}")
    private String uploadPathWin;

    public Map<String, Object> getInputStream(Integer id) throws IOException {
        Map<String, Object> map = new HashMap<>(2);
        SysFile sysFile = sysFileMapper.findById(id);
        map.put("f", sysFile);
        Path path = Paths.get(sysFile.getPath());
        map.put("s", Files.newInputStream(path));
        return map;
    }

    public Map<String, Object> trans(SysFile sysFile) {
        Map<String, Object> resultMap = new HashMap<>(4);
        resultMap.put("state", "SUCCESS");
        resultMap.put("original", sysFile.getOriginName() + "." + sysFile.getSuffixes());
        resultMap.put("type", sysFile.getSuffixes());
        String url = "/file/download" + "/" + sysFile.getId();
        resultMap.put("url", url);
        return resultMap;
    }

    @Transactional(rollbackFor = Exception.class)
    public SysFile fileUpload(MultipartFile multipartFile) throws Exception {
        Integer length = 100;
        String oFilename = multipartFile.getOriginalFilename();
        if (oFilename.length() > length) {
            throw new Exception("文件名太长");
        }
        String hash = Encry.md5(multipartFile.getBytes());
        String sub = hash.substring(0, 2);

        SysFile sysFile = new SysFile();
        //配置上传路径/年/月/hash前两位值(例: /2018/2/6a)
        String subPath = createUploadPath(sub);

        String baseName = FilenameUtils.getBaseName(oFilename);
        String fileType = FilenameUtils.getExtension(oFilename);

        sysFile.setOriginName(baseName);
        sysFile.setSuffixes(fileType);
        String newFileName = generateFileName(sysFile.getSuffixes());
        String realPath = subPath + File.separator + newFileName;
        sysFile.setCreateTime(new Date());
        sysFile.setPath(realPath);
        createDir(subPath);
        multipartFile.transferTo(new File(realPath));
        sysFileMapper.create(sysFile);
        return sysFile;
    }

    /**
     * 创建上传目录
     *
     * @param sub 描述此参数
     * @return string 描述此返回参数
     * @author zhouqi
     * @date 20180926
     * @since v1.0
     */
    private String createUploadPath(String sub) throws Exception {
        String rootPath = getPath();
        String uploadPath = rootPath + File.separator + DateUtils.getYear() + File.separator + DateUtils.getMonth() + File.separator + sub;
        boolean success = createDir(rootPath);
        if (!success) {
            throw new Exception("上传目录创建失败");
        }
        return uploadPath;
    }

    private String getPath() {
        String osName = "os.name";
        String win = "win";
        String path = uploadPath;
        if (System.getProperty(osName).toLowerCase().startsWith(win)) {
            path = uploadPathWin;
        }
        return path;
    }

    /**
     * 如果目录不存在则创建之
     *
     * @param path 描述此参数
     * @return boolean 描述此返回参数
     * @author zhouqi
     * @date 20180926
     * @since v1.0
     */
    private boolean createDir(String path) {
        File file = new File(path);
        if (file.exists()) {
            return true;
        } else {
            return file.mkdirs();
        }
    }

    /**
     * 使用currentTimeMillis作为文件名
     *
     * @param fileType 描述此参数
     * @return string 描述此返回参数
     * @author zhouqi
     * @date 20180926
     * @since v1.0
     */
    private String generateFileName(String fileType) {
        long uuid = System.currentTimeMillis();
        if (StringUtils.isNotBlank(fileType)) {
            return uuid + "." + fileType;
        } else {
            return String.valueOf(uuid);
        }
    }


}
